/**
 * 服务端渲染客户端动态交互
 */

const Vue = require('vue')
const express = require('express')
const fs = require('fs')

const renderer = require('vue-server-renderer').createRenderer()

const server = express()

/**
 * 服务端渲染直接输出的 HTML 页面，没有与客户端有关的 js 交互内容，
 * 因此这种直接输出 HTML 的方式不支持客户端的动态交互
 *
 * 解决方法：
 * 需要在服务器上使用 webpack 打包 Vue 应用程序，打包出来一份服务器应用程序和一份客户端应用程序
 * 将客户端应用程序在服务端渲染好的 HTML 内引入
 * 当浏览器渲染此 HTML 时，会载入客户端应用成员，将程序激活为动态的客户端应用
 */

server.get('/', (req, res) => {
  const app = new Vue({
    template: `
      <div id="app">
        <h1>{{ message }}</h1>
        <h2>客户端动态交互</h2>
        <div>
          <input v-model="message">
        </div>
        <div>
          <button @click="onClick">点击测试</button>
        </div>
      </div>
    `,
    data: {
      message: 'Vue 服务端渲染'
    },
    methods: {
      onClick () {
        console.log('Hello World')
      }
    },
  })

  renderer.renderToString(app, (err, html) => {
    if (err) {
      return res.status(500).end('Internal Server Error')
    }

    res.setHeader('Content-Type', 'text/html; charset=utf-8')
    res.end(`
      <!DOCTYPE html>
      <html lang="en">
      <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
      </head>
      <body>
        ${html}
      </body>
      </html>
    `)
  })
})

server.listen(3000, () => {
  console.log('server running at port 3000')
})
